package top.mcwebsite.markdown.render

import androidx.compose.foundation.layout.heightIn
import androidx.compose.foundation.layout.widthIn
import androidx.compose.foundation.text.InlineTextContent
import androidx.compose.runtime.Composable
import androidx.compose.runtime.snapshots.SnapshotStateMap
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.Placeholder
import androidx.compose.ui.text.PlaceholderVerticalAlign
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.unit.TextUnit
import androidx.compose.ui.unit.sp
import coil3.compose.AsyncImage
import coil3.compose.AsyncImagePainter
import coil3.compose.LocalPlatformContext
import coil3.request.ImageRequest
import coil3.size.Size

const val IMAGE_ID_PREFIX = "MARKDOWN_IMAGE_ID"

data class ImageState(
    val width: TextUnit = 16.sp,
    val height: TextUnit = 16.sp,
    val link: String,
    val alt: String
)

internal fun buildImageState(imageId: String, alt: String): ImageState {
    return ImageState(link = imageId, alt = alt)
}

fun AnnotatedString.getImageStates(): Map<String, ImageState> {
    return buildMap {
        this@getImageStates.getStringAnnotations("androidx.compose.foundation.text.inlineContent", 0, this@getImageStates.length).forEach {
            val (imageId, url, alt) = it.item.split(" ")
            val imageState = buildImageState(url, alt)
            put(it.item, imageState)
        }
    }
}

@Composable
fun AnnotatedString.getInlineImage(imageStates: SnapshotStateMap<String, ImageState>): Map<String, InlineTextContent> {
    return  getStringAnnotations("androidx.compose.foundation.text.inlineContent", 0, length)
        .onEach { println("item = ${it}") }
        .filter { it.item.startsWith(IMAGE_ID_PREFIX) }
        .map { range ->
            range.item to InlineTextContent(
                Placeholder(
                    width = imageStates[range.item]!!.width,
                    height = imageStates[range.item]!!.height,
                    placeholderVerticalAlign = PlaceholderVerticalAlign.Top
                )
            ) {
                val (_, url, _) = range.item.split(" ")
                val density = LocalDensity.current
                AsyncImage(
                    model = ImageRequest.Builder(LocalPlatformContext.current)
                        .data(url)
                        .size(Size.ORIGINAL)
                        .build(),
                    contentDescription = null,
                    onState = { s ->
                        if (s is AsyncImagePainter.State.Success) {
                            val image = s.result.image
                            val (width, height) = with(density) {
                                image.width.toSp() to image.height.toSp()
                            }
                            imageStates[range.item] = imageStates[range.item]!!.copy(
                                width = width,
                                height = height
                            )
                            println("image = ${image.width to image.height}")
                        }
                    },
                    modifier = Modifier.widthIn(max = with(density) { imageStates[range.item]!!.width.toDp() })
                        .heightIn(max = with(density) { imageStates[range.item]!!.height.toDp()})
                )
            }
        }.associate { it.first to it.second }
}